use plugin_manager::{PluginBase, ServicePlugin, ServiceHostFunctions, ValidateCertChainFn, GetUnmatchedMeasurementsFn, QueryConfigerationFn, serde_json};

/// A simple test service plugin for testing the plugin manager
pub struct TestServicePlugin {
    plugin_type: String,
    validate_cert_chain: ValidateCertChainFn,
    get_unmatched_measurements: GetUnmatchedMeasurementsFn,
    query_configeration: QueryConfigerationFn,
}

impl TestServicePlugin {
    fn new(
        plugin_type: String,
        validate_cert_chain: ValidateCertChainFn, 
        get_unmatched_measurements: GetUnmatchedMeasurementsFn, 
        query_configeration: QueryConfigerationFn) -> Self {
        Self {
            plugin_type,
            validate_cert_chain,
            get_unmatched_measurements,
            query_configeration,
        }
    }
}

impl PluginBase for TestServicePlugin {
    fn plugin_type(&self) -> &str {
        self.plugin_type.as_str()
    }
}

impl ServicePlugin for TestServicePlugin {
    fn get_sample_output(&self) -> String {
        let cert_verification_result = (self.validate_cert_chain)(b"test");
        let unmatched_value = (self.get_unmatched_measurements)(&vec![String::from("test")], &vec![String::from("test")], "test");
        let config = (self.query_configeration)(String::from("test"));
        serde_json::json!({
            "cert_verification_result": cert_verification_result,
            "unmatched_value": unmatched_value,
            "config": config
        }).to_string()
    }
    
    fn parse_evidence(&self, evidence: &serde_json::Value, nonce: Option<String>) -> Result<serde_json::Value, String> {
        Ok(evidence.clone())
    }
}

#[no_mangle]
pub fn create_plugin(host_functions: &ServiceHostFunctions, plugin_type: &str) -> Option<Box<dyn ServicePlugin>> {
    // Extract the functions from the host functions struct
    let validate_cert_chain = host_functions.validate_cert_chain;
    let get_unmatched_measurements = host_functions.get_unmatched_measurements;
    let query_configeration = host_functions.query_configeration;
    
    // Create a new instance with the host functions
    Some(Box::new(TestServicePlugin::new(String::from(plugin_type), validate_cert_chain, get_unmatched_measurements, query_configeration)))
}
